<?php

declare(strict_types=1);

namespace Tool\Database;

use Marx\Console\Color;

/**
 * 字段基类.
 */
abstract class AbstractColumn
{
    /**
     * 被调用次数.
     */
    protected int $count = 0;

    /**
     * 扩展参数.
     */
    protected array $extArgs = [];

    /**
     * 字段信息.
     */
    private array $column;

    public function __construct(array &$column)
    {
        $this->column = $column;
    }

    /**
     * 获取mock的数据.
     *
     * @return null|float|int|string
     */
    final public function getData()
    {
        ++$this->count;

        return $this->mock();
    }

    /**
     * 询问扩展参数.
     */
    public function askExtArgs(): ?string
    {
        if (!$this->extArgs) {
            return null;
        }

        return 'please input value range['.Color::yellow(implode(',', $this->extArgs)).', n to skip]';
    }

    /**
     * 添加扩展参数.
     */
    public function setExtArgs(array $extArgs)
    {
        if ($extArgs) {
            $this->extArgs = $extArgs;
        }
    }

    /**
     * mock数据.
     *
     * @return null|float|int|string
     */
    abstract protected function mock();

    protected function nullable()
    {
        return 'YES' === $this->column['IS_NULLABLE'];
    }

    protected function isUnique()
    {
        return 'UNI' === $this->column['COLUMN_KEY'];
    }

    protected function defaultValue($default = null)
    {
        if ($this->nullable($this->column)) {
            $default = null;
        }

        return $this->column['COLUMN_DEFAULT'] ?? $default;
    }

    protected function getName(): string
    {
        return $this->column['COLUMN_NAME'];
    }

    protected function getType(): string
    {
        return $this->column['DATA_TYPE'];
    }

    protected function getMaxLen(): int
    {
        return $this->column['CHARACTER_MAXIMUM_LENGTH'];
    }

    protected function getPrecision(): int
    {
        return $this->column['NUMERIC_PRECISION'];
    }

    protected function getScale(): int
    {
        return $this->column['NUMERIC_SCALE'];
    }

    protected function getComment(): string
    {
        return $this->column['COLUMN_COMMENT'];
    }

    protected function isPrimaryKey(): bool
    {
        return 'PRI' === $this->column['COLUMN_KEY'] && 'auto_increment' === $this->column['EXTRA'];
    }
}
